package com.baseweb.webadmin.controller.admin;


import com.baseweb.webadmin.controller.BaseController;
import com.baseweb.webadmin.core.model.bvo.RescBvo;
import com.baseweb.webadmin.core.model.bvo.RescTreeBvo;
import com.baseweb.webadmin.core.model.pojo.*;
import com.baseweb.webadmin.service.*;
import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping(value = "/role")
public class RoleController extends BaseController {
    private String prefix = "/role";

    @Autowired
    private RoleService roleService;

    @Autowired
    private UserService userService;

    @Autowired
    private RoleRescService roleRescService;

    @Autowired
    private RoleAppService roleAppService;

    @RequestMapping(value = "/roleManager", method = RequestMethod.GET)
    public String roleManager(Model model) {
        return prefix + "/roleManager";
    }

    /**
     * 添加权限
     */
    @RequestMapping(value = "/updateRoleApp", method = RequestMethod.POST)
    public void updateRoleApp(
            Model model,
            @RequestParam("roleId") Integer roleId,
            @RequestParam(value = "appId", required = false) String apps) throws Exception {
        //不能修改直接拥有的权限
        boolean isDirect = isDirectRoleOfUser(roleId);
        if (isDirect) {
            model.addAttribute("msg", "FAIL");
            return;
        }

        RoleAppExample example = new RoleAppExample();
        RoleAppExample.Criteria criteria = example.createCriteria();
        criteria.andRoleIdEqualTo(roleId);
        roleAppService.deleteByExample(example);

        if (StringUtils.isNotBlank(apps)) {
            String[] s = apps.split(",");
            for (String appId : s) {
                RoleApp app = new RoleApp();
                app.setAppId(Integer.valueOf(appId));
                app.setRoleId(roleId);
                roleAppService.insertSelective(app);
            }
        }

        model.addAttribute("msg", "SUCCESS");
        return;
    }

    /**
     * 展示权限
     */
    @RequestMapping(value = "/viewRoles", method = RequestMethod.GET)
    public String viewRoles(Model model) {
        List<Role> roleList = roleService.selectRoles();
        model.addAttribute("roleList", roleList);
        return prefix + "/viewRoles";
    }

    /**
     * 展示权限(受限)
     */
    @RequestMapping(value = "/selectRoles")
    public String selectRoles(Model model) {
        //   List<Role> roleList = roleService.selectLimitRoles();
        List<Role> roleList = roleService.selectRoles();
        model.addAttribute("roleList", roleList);
        return prefix + "/viewRoles";
    }

    /**
     * 跳转添加权限页面
     */
    @RequestMapping(value = "/addRoleview", method = RequestMethod.GET)
    public String addRoleview(Model model) {
        Integer id = 0;
        Integer fatherId = id;
        List<Resc> rescList = roleRescService.getRescByFatherId(fatherId);
        List<RescBvo> list = new ArrayList<RescBvo>();
        for (Resc resc : rescList) {
            RescBvo rescBvo = new RescBvo();
            rescBvo.setFatherId(resc.getFatherId());
            rescBvo.setName(resc.getName());
            rescBvo.setRescId(resc.getId());
            rescBvo.setDesc(resc.getDescn());
            List<RescBvo> list1 = new ArrayList<RescBvo>();
            List<Resc> rescList1 = roleRescService.getRescByFatherId(resc.getId());
            for (Resc resc1 : rescList1) {
                RescBvo rescBvo1 = new RescBvo();
                rescBvo1.setFatherId(resc1.getFatherId());
                rescBvo1.setName(resc1.getName());
                rescBvo1.setRescId(resc1.getId());
                rescBvo1.setDesc(resc1.getDescn());
                List<RescBvo> list2 = new ArrayList<RescBvo>();
                List<Resc> rescList2 = roleRescService.getRescByFatherId(resc1.getId());
                for (Resc resc2 : rescList2) {
                    RescBvo rescBvo2 = new RescBvo();
                    rescBvo2.setFatherId(resc2.getFatherId());
                    rescBvo2.setName(resc2.getName());
                    rescBvo2.setRescId(resc2.getId());
                    rescBvo2.setDesc(resc2.getDescn());
                    list2.add(rescBvo2);
                }
                rescBvo1.setList(list2);
                list1.add(rescBvo1);
            }
            rescBvo.setList(list1);
            list.add(rescBvo);
        }
        model.addAttribute("rescBvoList", list);
        return prefix + "/addRoleview";
    }

    /**
     * 添加权限
     */
    @RequestMapping(value = "/addRole", method = RequestMethod.POST)
    public String addRole(@RequestParam("roleName") String roleName,
                          HttpServletRequest request) {
        Role role = new Role();
        role.setRoleName(roleName);
        roleService.insertRole(role);
        Role currentRole = roleService.selectRoleByNameAndDescn(roleName);
        String rescIds[] = request.getParameterValues("rescIds");
        for (int i = 0; i < rescIds.length; i++) {
            RescRoleKey rescRole = new RescRoleKey();
            rescRole.setRescId(new Integer(rescIds[i]));
            rescRole.setRoleId(currentRole.getId());
            roleRescService.insertRescRole(rescRole);
        }
        writeLog(request, "添加角色", "添加角色(" + roleName + ")");
        return "redirect:/role/viewRoles";
    }

    /**
     * 删除权限
     *
     * @param roleId
     */
    @RequestMapping(value = "/deleteRole", method = RequestMethod.GET)
    public String deleteRole(@RequestParam("roleId") Integer roleId, HttpServletRequest request) {
        roleService.deleteRoleById(roleId);
        roleRescService.deleteRescRoleByRoleId(roleId);
        userService.deleteUserRoleByRoleId(roleId);
        writeLog(request, "删除角色", "删除角色(id:" + roleId + ")");
        return "redirect:/role/viewRoles";
    }

    /**
     * 跳转权限页面
     *
     * @param roleId
     * @param model
     * @return
     */
    @RequestMapping(value = "/updateRoleView", method = RequestMethod.GET)
    public String updateRoleView(@RequestParam("roleId") Integer roleId, Model model) {
        Role role = roleService.selectRoleById(roleId);
        List<RescRoleKey> rescRoleList = roleRescService.selectRescRoleKeyByRoleId(roleId);
        List<Resc> rescList = roleRescService.selectRescs();
        List<Resc> checkedRescList = new ArrayList<Resc>();
        for (int i = 0; i < rescList.size(); i++) {
            Resc resc = rescList.get(i);
            int j = -1;
            for (RescRoleKey rescRoleKey : rescRoleList) {
                if (resc.getId() == rescRoleKey.getRescId()) {
                    checkedRescList.add(resc);
                    j = i;
                    break;
                }
            }
        }

//        rescList = null;
        Integer id = 0;
        Integer fatherId = id;
        rescList = roleRescService.getRescByFatherId(fatherId);
        List<RescBvo> list = new ArrayList<RescBvo>();
        for (Resc resc : rescList) {
            RescBvo rescBvo = new RescBvo();
            rescBvo.setFatherId(resc.getFatherId());
            rescBvo.setName(resc.getName());
            rescBvo.setRescId(resc.getId());
            rescBvo.setDesc(StringUtils.trimToNull(resc.getDescn()));
            rescBvo.setShowMenu(resc.getShowMenu().intValue());
            List<RescBvo> list1 = new ArrayList<RescBvo>();
            List<Resc> rescList1 = roleRescService.getRescByFatherId(resc.getId());
            for (Resc resc1 : rescList1) {
                RescBvo rescBvo1 = new RescBvo();
                rescBvo1.setFatherId(resc1.getFatherId());
                rescBvo1.setName(resc1.getName());
                rescBvo1.setRescId(resc1.getId());
                rescBvo1.setDesc(StringUtils.trimToNull(resc1.getDescn()));
                rescBvo1.setShowMenu(resc1.getShowMenu().intValue());
                List<RescBvo> list2 = new ArrayList<RescBvo>();
                List<Resc> rescList2 = roleRescService.getRescByFatherId(resc1.getId());
                for (Resc resc2 : rescList2) {
                    RescBvo rescBvo2 = new RescBvo();
                    rescBvo2.setFatherId(resc2.getFatherId());
                    rescBvo2.setName(resc2.getName());
                    rescBvo2.setRescId(resc2.getId());
                    rescBvo2.setDesc(StringUtils.trimToNull(resc2.getDescn()));
                    rescBvo2.setShowMenu(resc2.getShowMenu().intValue());
                    list2.add(rescBvo2);
                }
                rescBvo1.setList(list2);
                list1.add(rescBvo1);
            }
            rescBvo.setList(list1);
            list.add(rescBvo);
        }
        model.addAttribute("rescBvoList", list);

        model.addAttribute("role", role);
        model.addAttribute("rescList", rescList);
        model.addAttribute("checkedRescList", checkedRescList);
        return prefix + "/updateRoleView";
    }

    /**
     * 修改权限
     *
     * @param roleId
     * @param roleName
     * @param request
     * @return
     */
    @RequestMapping(value = "/updateRole", method = RequestMethod.POST)
    public String updateRole(@RequestParam("roleId") Integer roleId,
                             @RequestParam("roleName") String roleName,
                             HttpServletRequest request) {
        Role role = new Role();
        role.setId(roleId);
        role.setRoleName(roleName);
        roleService.updateRole(role);
        roleRescService.deleteRescRoleByRoleId(roleId);
        String rescIds[] = request.getParameterValues("rescIds");
        if (rescIds != null) {
            for (int i = 0; i < rescIds.length; i++) {
                RescRoleKey rescRole = new RescRoleKey();
                rescRole.setRescId(new Integer(rescIds[i]));
                rescRole.setRoleId(roleId);
                roleRescService.insertRescRole(rescRole);
            }
        }
        writeLog(request, "编辑角色权限", "编辑角色权限(角色id:" + roleId + "|" + roleName + ")");
        return "redirect:/role/viewRoles";
    }

    /**
     * 判断权限是否存在
     *
     * @param roleName
     * @param model
     * @return
     */
    @RequestMapping(value = "/isRole", method = RequestMethod.GET)
    public String isRole(@RequestParam("roleName") String roleName,
                         Model model) {
        try {
            roleName = URLDecoder.decode(roleName, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        Boolean isRole = roleService.isRole(roleName);
        model.addAttribute("isRole", isRole);
        return null;
    }

    /**
     * 查询数据权限
     * add by lxl
     *
     * @param model
     * @return
     */
    @RequestMapping(value = "/getRoleTree")
    public void getRoleTree(Model model) {
        String userName = getUserName();
        if (userName != null) {
            User user = userService.selectByName(userName);
            if (user != null) {
                List<Role> list = roleService.selectRolesByUser(user.getId());
                model.addAttribute("list", list);
                return;
            }
        }
        return;
    }

    /**
     * 查询数据权限
     * add by lxl
     * <p/>
     * 如果是角色是超级管理员  则直接加载所有权限
     * 如果是当前用户拥有的直接角色 则不能去查找父角色的权限
     * 如果是间接角色 则需要加载父用户的权限
     *
     * @param model
     * @return
     */
    @RequestMapping(value = "/getRescByRole")
    public void getRescByRole(Model model,
                              @RequestParam(value = "id") Integer id) {
        boolean isDirect;
        try {
            isDirect = isDirectRoleOfUser(id);
        } catch (Exception e) {
            model.addAttribute("msg", e.getMessage());
            e.printStackTrace();
            return;
        }

        //获取当前role
        Role role = roleService.selectRoleById(id);
        if (role != null) {
            List<RescTreeBvo> bvos = new ArrayList<RescTreeBvo>();

            //超级管理员
            if (role.getParentId() == 0) {
                List<Resc> list = roleRescService.selectRescs();
                for (Resc resc : list) {
                    RescTreeBvo bvo = RescTreeBvo.copyFromResc(resc);
                    bvo.setChecked(true);
                    bvos.add(bvo);
                }
            } else {
                if (isDirect) {
                    List<Resc> list = roleRescService.getRescByRole(id);

                    for (Resc resc : list) {
                        RescTreeBvo bvo = RescTreeBvo.copyFromResc(resc);
                        bvo.setChecked(false);
                        bvos.add(bvo);
                    }
                } else {
                    //如果其父角色是超级管理员 那么他可选择所有的权限
                    Role parentRole = roleService.selectRoleById(role.getParentId());
                    List<Resc> list;
                    if (parentRole != null && parentRole.getParentId() == 0) {
                        list = roleRescService.selectRescs();
                    } else {
                        list = roleRescService.getRescByRole(role.getParentId());
                    }
                    List<Integer> rescs = new ArrayList<Integer>();

                    //获取当前角色的资源
                    if (id != null && id > 0) {
                        List<RescRoleKey> keys = roleRescService.selectRescRoleKeyByRoleId(id);
                        for (RescRoleKey key : keys) {
                            rescs.add(key.getRescId());
                        }
                    }

                    for (Resc resc : list) {
                        RescTreeBvo bvo = RescTreeBvo.copyFromResc(resc);
                        if (rescs.contains(resc.getId())) {
                            bvo.setChecked(true);
                        } else {
                            bvo.setChecked(false);
                        }
                        bvos.add(bvo);
                    }
                }
            }

            model.addAttribute("isDirect", isDirect);
            model.addAttribute("list", bvos);
        }
        return;
    }

    /**
     * 添加权限
     */
    @RequestMapping(value = "/addRoleNew", method = RequestMethod.POST)
    public void addRole2(
            Model model,
            HttpServletRequest request,
            @RequestParam("roleName") String roleName,
            @RequestParam("pid") Integer pid) {
        Role role = new Role();
        role.setRoleName(roleName);
        role.setParentId(pid);
        roleService.insertRole(role);
        Role currentRole = roleService.selectRoleByNameAndDescn(roleName);

        model.addAttribute("role", currentRole);
        writeLog(request, "添加角色", "添加角色(" + roleName + ")");
        return;
    }

    /**
     * 添加权限
     */
    @RequestMapping(value = "/updateRoleResc", method = RequestMethod.POST)
    public void updateRoleResc(
            Model model,
            HttpServletRequest request,
            @RequestParam("roleId") Integer roleId,
            @RequestParam("list") String list) throws Exception {
        //不能修改直接拥有的权限
        boolean isDirect = isDirectRoleOfUser(roleId);
        if (isDirect) {
            model.addAttribute("msg", "FAIL");
            return;
        }

        ObjectMapper mapper = new ObjectMapper();
        List<Map> value = mapper.readValue(list, ArrayList.class);
        for (Map m : value) {
            int rescId = (Integer) m.get("id");
            boolean checked = (Boolean) m.get("checked");

            RescRoleKey key = new RescRoleKey();
            key.setRoleId(roleId);
            key.setRescId(rescId);
            if (checked) {
                roleRescService.insertRescRole(key);
            } else {
                roleRescService.deleteByPrimaryKey(key);
            }
        }

        model.addAttribute("msg", "SUCCESS");
        return;
    }

    /**
     * 添加权限
     */
    @RequestMapping(value = "/updateRoleName", method = RequestMethod.POST)
    public void updateRoleName(
            Model model,
            HttpServletRequest request,
            @RequestParam("roleId") Integer roleId,
            @RequestParam("roleName") String name) throws Exception {
        //不能重命名直接拥有的权限
        boolean isDirect = isDirectRoleOfUser(roleId);
        if (isDirect) {
            model.addAttribute("msg", "FAIL");
            return;
        }

        if (StringUtils.isNotBlank(name)) {
            Role role = roleService.selectRoleById(roleId);
            role.setRoleName(name.trim());
            roleService.updateRole(role);
            model.addAttribute("msg", "SUCCESS");
        } else {
            model.addAttribute("msg", "INVALID_PARAM");
        }
        return;
    }

    /**
     * 删除角色
     *
     * @param roleId
     */
    @RequestMapping(value = "/deleteRoleNew")
    public void deleteRoleNew(Model model,
                              HttpServletRequest request,
                              @RequestParam("roleId") Integer roleId) throws Exception {
//        String userName = getUserName();
//        User user = userService.selectByName(userName);
//        if (user == null) {
//            model.addAttribute("msg", "USER_NOT_EXIST");
//            return;
//        }
//
//        //不能删除直接拥有的权限
//        List<Role> roles = roleService.selectRoleListByUser(user.getId().toString());
//        for (Role r : roles) {
//            if (r.getId().longValue() == roleId.longValue()) {
//                model.addAttribute("msg", "FAIL");
//                return;
//            }
//        }

        //不能删除直接拥有的权限
        boolean isDirect = isDirectRoleOfUser(roleId);
        if (isDirect) {
            model.addAttribute("msg", "FAIL");
            return;
        }

        deleteRoleRecursive(request, roleId);
        model.addAttribute("msg", "SUCCESS");
        return;
    }

    //递归地删除角色
    private void deleteRoleRecursive(HttpServletRequest request, Integer roleId) {
        RoleExample example = new RoleExample();
        RoleExample.Criteria criteria = example.createCriteria();
        criteria.andParentIdEqualTo(roleId);
        List<Role> roles = roleService.selectByExample(example);
        for (Role role : roles) {
            deleteRoleRecursive(request, role.getId());
        }

        roleService.deleteRoleById(roleId);
        roleRescService.deleteRescRoleByRoleId(roleId);
        userService.deleteUserRoleByRoleId(roleId);
        writeLog(request, "删除角色", "删除角色(id:" + roleId + ")");
    }

    /**
     * 是否是用户直接拥有的角色
     *
     * @param roleId
     * @return
     * @throws Exception
     */
    private boolean isDirectRoleOfUser(long roleId) throws Exception {
        String userName = getUserName();
        User user = userService.selectByName(userName);
        if (user == null) {
            throw new Exception("USER_NOT_EXIST");
        }

        List<Role> roleList = roleService.selectRoleListByUser(user.getId().toString());
        for (Role r : roleList) {
            if (r.getId().longValue() == roleId) {
                return true;
            }
        }

        return false;
    }

    /**
     * 根据用户角色查找所有资源
     *
     * @return
     */
    private List<Resc> getRescListByRole() {
        User currentUser = userService.selectByName(getUserName());  //获得当前用户
        List<Role> currentRoles = roleService.selectRoleListByUser(currentUser.getId().toString());   //根据当前用户活动当前用户的所有角色

        List<Integer> resourceIdList = new ArrayList<Integer>();
        List<RescRoleKey> keys = new ArrayList<RescRoleKey>();
        //获取当前角色的资源 id
        for (Role role : currentRoles) {
            keys = roleRescService.selectRescRoleKeyByRoleId(role.getId());
            for (RescRoleKey key : keys) {
                if (!resourceIdList.contains(key)) {
                    resourceIdList.add(key.getRescId());
                }
            }
        }
        List<Resc> rescsList = roleRescService.getRescByIds(resourceIdList);
        return rescsList;
    }
}
